import os
import glob
import json
import re
import requests
from PyPDF2 import PdfReader
from fpdf import FPDF
import time
from datetime import datetime


class PDFSummarizer:
    def __init__(self):
        # 初始化DeepSeek API设置
        self.api_url = "https://api.deepseek.com/v1/chat/completions"
        self.api_key = os.environ.get("DEEPSEEK_API_KEY")
        self.model = "deepseek-chat"
        self.max_retries = 3
        self.timeout = 90

        # 字体设置 - 使用新版FPDF字体添加方式
        self.font_path = "C:/Windows/Fonts/simsun.ttc"  # 系统宋体
        self.font_name = "SimSun"
        self._setup_font()

    def _setup_font(self):
        """设置字体，使用新版FPDF API"""
        try:
            if not os.path.exists(self.font_path):
                fallback_fonts = [
                    "C:/Windows/Fonts/simhei.ttf",
                    "C:/Windows/Fonts/msyh.ttc",
                    "C:/Windows/Fonts/msyhbd.ttc",
                ]

                for font in fallback_fonts:
                    if os.path.exists(font):
                        self.font_path = font
                        self.font_name = os.path.splitext(os.path.basename(font))[0]
                        print(f"使用备用字体: {self.font_name}")
                        break
                else:
                    raise FileNotFoundError("未找到系统中文TrueType字体")

            test_pdf = FPDF()
            test_pdf.add_page()
            test_pdf.add_font(family=self.font_name, fname=self.font_path)
            test_pdf.set_font(self.font_name, size=10)
            test_pdf.cell(text="中文测试", new_x="LMARGIN", new_y="NEXT")
            print(f"字体设置成功: {self.font_name}")

        except Exception as e:
            print(f"字体设置警告: {str(e)}")
            self.font_name = "Helvetica"

    def extract_text_from_pdf(self, pdf_path):
        """从PDF文件中提取文本"""
        text = ""
        with open(pdf_path, 'rb') as file:
            reader = PdfReader(file)
            for page in reader.pages:
                page_text = page.extract_text()
                if page_text:
                    cleaned_text = re.sub(r'[\x00-\x1F\x7F-\x9F\u200B-\u200D\uFEFF]', ' ', page_text)
                    text += cleaned_text + "\n"
        return text.strip()

    def summarize_with_deepseek(self, text, filename):
        """使用DeepSeek API总结PDF内容"""
        prompt = f"""请从以下年报内容中提取以下关键信息，并以JSON格式返回：

        1. 行业状况分析：
           - 光伏行业整体发展情况
           - 风电行业整体发展情况
           - 行业竞争格局变化
           - 政策环境分析

        2. 主要产品数据：
           - 光伏逆变器：销售额、毛利率、同比变动
           - 风电变流器：销售额、毛利率、同比变动  
           - 储能系统：销售额、毛利率、同比变动
           - 其他主要产品：销售额、毛利率、同比变动

        3. 公司经营情况：
           - 研发投入及重点方向
           - 市场拓展情况
           - 产能建设进展
           - 重要战略合作

        4. 财务表现：
           - 营业收入及增长率
           - 净利润及增长率
           - 现金流状况
           - 资产负债率

        要求：
        - 数据请尽量精确，标注单位（亿元、百分比等）
        - 同比变动请注明增减方向和幅度
        - 使用规范的行业术语
        - 重要数据请注明来源章节

        年报文件名: {filename}
        年报内容:
        {text[:15000]}
        """

        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }

        payload = {
            "model": self.model,
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.1,  # 降低随机性以提高数据准确性
            "max_tokens": 4000,
            "response_format": {"type": "json_object"}
        }

        for attempt in range(self.max_retries):
            try:
                response = requests.post(
                    self.api_url,
                    headers=headers,
                    json=payload,
                    timeout=self.timeout
                )

                if response.status_code == 200:
                    data = response.json()
                    content = data["choices"][0]["message"]["content"]

                    if content.strip().startswith("```json"):
                        content = re.sub(r'^```json\s*|\s*```$', '', content, flags=re.MULTILINE)

                    try:
                        summary = json.loads(content)
                        # 数据校验
                        if not isinstance(summary, dict):
                            raise ValueError("返回格式不是JSON对象")
                        return summary
                    except (json.JSONDecodeError, ValueError) as e:
                        print(f"JSON解析错误: {str(e)}")
                        return {"error": "API返回格式不正确"}

                elif response.status_code == 429:
                    wait_time = int(response.headers.get("Retry-After", 10))
                    time.sleep(wait_time)
                    continue

                else:
                    print(f"API请求失败，状态码: {response.status_code}")
                    print(f"响应内容: {response.text[:200]}")

            except requests.RequestException as e:
                print(f"请求失败: {str(e)}")

            if attempt < self.max_retries - 1:
                time.sleep(min(5 * (attempt + 1), 30))

        return {"error": "无法从DeepSeek获取总结"}

    def _create_data_table(self, pdf, data, title):
        """创建数据表格"""
        pdf.set_font(self.font_name, 'B', 12)
        pdf.cell(0, 8, title, new_x="LMARGIN", new_y="NEXT")
        pdf.set_font(self.font_name, '', 10)

        # 表头
        pdf.set_fill_color(200, 220, 255)
        pdf.cell(60, 8, "产品名称", border=1, fill=True)
        pdf.cell(40, 8, "销售额", border=1, fill=True)
        pdf.cell(40, 8, "毛利率", border=1, fill=True)
        pdf.cell(40, 8, "同比变动", border=1, fill=True, new_x="LMARGIN", new_y="NEXT")

        # 表格内容
        for product, values in data.items():
            pdf.cell(60, 8, product, border=1)
            pdf.cell(40, 8, str(values.get("sales", "N/A")), border=1)
            pdf.cell(40, 8, str(values.get("gross_margin", "N/A")), border=1)
            pdf.cell(40, 8, str(values.get("yoy_change", "N/A")), border=1, new_x="LMARGIN", new_y="NEXT")

        pdf.ln(5)

    def create_summary_pdf(self, summaries, output_path):
        """创建包含所有总结的PDF文件"""
        pdf = FPDF()
        pdf.set_auto_page_break(auto=True, margin=15)

        try:
            pdf.add_font(family=self.font_name, fname=self.font_path)
            pdf.add_font(family=self.font_name, fname=self.font_path, style="B")
        except:
            self.font_name = "Helvetica"

        # 设置文档属性
        pdf.set_title("年报分析报告")
        pdf.set_author("PDF Summarizer")

        # 封面页
        pdf.add_page()
        pdf.set_font(self.font_name, 'B', 24)
        pdf.cell(0, 40, "新能源行业年报分析报告", new_x="LMARGIN", new_y="NEXT", align="C")
        pdf.set_font(self.font_name, '', 16)
        pdf.cell(0, 20, f"生成日期: {datetime.now().strftime('%Y-%m-%d')}", new_x="LMARGIN", new_y="NEXT", align="C")
        pdf.image("logo.png", x=80, w=50) if os.path.exists("logo.png") else None
        pdf.ln(30)

        # 目录页
        pdf.add_page()
        pdf.set_font(self.font_name, 'B', 16)
        pdf.cell(0, 10, "目录", new_x="LMARGIN", new_y="NEXT")
        pdf.set_font(self.font_name, '', 12)

        for i, (filename, _) in enumerate(summaries.items(), 1):
            pdf.cell(0, 8, f"{i}. {filename}", new_x="LMARGIN", new_y="NEXT")

        # 分析报告页
        for filename, summary in summaries.items():
            pdf.add_page()
            pdf.set_font(self.font_name, 'B', 16)
            pdf.cell(0, 10, f"文件分析: {filename}", new_x="LMARGIN", new_y="NEXT")

            if isinstance(summary, dict):
                # 行业分析部分
                pdf.set_font(self.font_name, 'B', 14)
                pdf.cell(0, 8, "一、行业状况分析", new_x="LMARGIN", new_y="NEXT")
                pdf.set_font(self.font_name, '', 12)

                industry = summary.get("industry_analysis", {})
                for sector, content in industry.items():
                    pdf.set_font(self.font_name, 'B', 12)
                    pdf.cell(0, 8, f"{sector}:", new_x="LMARGIN", new_y="NEXT")
                    pdf.set_font(self.font_name, '', 12)
                    pdf.multi_cell(0, 6, str(content))
                    pdf.ln(2)

                # 产品销售数据表格
                products = summary.get("products", {})
                if products:
                    self._create_data_table(pdf, products, "二、主要产品销售数据")

                # 财务表现
                pdf.set_font(self.font_name, 'B', 14)
                pdf.cell(0, 8, "三、财务表现", new_x="LMARGIN", new_y="NEXT")
                pdf.set_font(self.font_name, '', 12)

                finance = summary.get("financial_performance", {})
                for item, value in finance.items():
                    pdf.cell(60, 8, item)
                    pdf.cell(0, 8, str(value), new_x="LMARGIN", new_y="NEXT")

                # 公司经营
                pdf.set_font(self.font_name, 'B', 14)
                pdf.cell(0, 8, "四、公司经营情况", new_x="LMARGIN", new_y="NEXT")
                pdf.set_font(self.font_name, '', 12)

                operations = summary.get("operations", {})
                for area, content in operations.items():
                    pdf.set_font(self.font_name, 'B', 12)
                    pdf.cell(0, 8, f"{area}:", new_x="LMARGIN", new_y="NEXT")
                    pdf.set_font(self.font_name, '', 12)
                    pdf.multi_cell(0, 6, str(content))
                    pdf.ln(2)
            else:
                pdf.multi_cell(0, 8, str(summary))

            pdf.ln(10)

        # 保存PDF
        try:
            temp_path = os.path.join(os.environ["TEMP"], os.path.basename(output_path))
            pdf.output(temp_path)
            os.replace(temp_path, output_path)
            print(f"PDF文件已生成: {output_path}")
            return True
        except Exception as e:
            print(f"保存PDF失败: {str(e)}")
            return False

    def process_directory(self, input_dir):
        """处理目录中的所有PDF文件"""
        if not os.path.exists(input_dir):
            print(f"目录不存在: {input_dir}")
            return None

        pdf_files = glob.glob(os.path.join(input_dir, "*.pdf"))
        if not pdf_files:
            print(f"目录中没有找到PDF文件: {input_dir}")
            return None

        summaries = {}
        for pdf_file in pdf_files:
            try:
                filename = os.path.basename(pdf_file)
                print(f"正在处理: {filename}")

                text = self.extract_text_from_pdf(pdf_file)
                if not text.strip():
                    print(f"警告: {filename} 没有提取到文本内容")
                    summaries[filename] = "无法从PDF提取文本内容"
                    continue

                summary = self.summarize_with_deepseek(text, filename)
                summaries[filename] = summary
                print(f"已完成: {filename}")

            except Exception as e:
                print(f"处理文件 {pdf_file} 时出错: {str(e)}")
                summaries[filename] = f"处理错误: {str(e)}"

        return summaries


if __name__ == "__main__":
    input_dir = r"d:\pycharmprojects\pythonproject\阳光电源年报"
    output_dir = r"C:\temp"
    os.makedirs(output_dir, exist_ok=True)
    output_pdf = os.path.join(output_dir, "年报分析报告.pdf")

    summarizer = PDFSummarizer()

    if not summarizer.api_key:
        print("错误: 未设置DEEPSEEK_API_KEY环境变量")
        exit(1)

    print("开始分析年报文件...")
    summaries = summarizer.process_directory(input_dir)

    if summaries:
        print("生成分析报告...")
        if summarizer.create_summary_pdf(summaries, output_pdf):
            print(f"分析报告已保存: {output_pdf}")
            print("请使用Adobe Reader查看完整效果")
        else:
            print("生成报告失败")
    else:
        print("没有生成任何分析结果")